import type { AxiosRequestConfig } from 'axios'

import { uuid } from '@/utils/uuid'

/**
 * @description 存储请求的 Map 对象
 */
const requestMap: Map<
  string,
  {
    controller: AbortController
    cancelConfig: AxiosRequestConfig['cancelConfig']
  }
> = new Map()

/**
 * @description 生成请求的唯一标识
 * @param param0
 * @returns
 */
const getRequestId = ({ url, method, params, data, cancelConfig }: AxiosRequestConfig) => {
  return cancelConfig!.customRequestId
    ? uuid(cancelConfig!.customRequestId)
    : uuid(JSON.stringify({ url, method, params, data }))
}

/**
 * @description 设置请求的 Map 对象
 * @param config
 * @returns
 */
export const setReqMapItem = (config: AxiosRequestConfig) => {
  const requestId = getRequestId(config)
  const controller = new AbortController()
  requestMap.set(requestId, {
    controller,
    cancelConfig: config.cancelConfig
  })
  return {
    signal: controller.signal,
    requestId
  }
}

/**
 * @description 删除请求的 Map 对象
 * @param requestId
 */
export const deleteReqMapItem = (requestId: string) => {
  requestMap.delete(requestId)
}

/**
 * @description 取消单个请求
 * @param requestId
 */
export const cancelSingleRequest = (requestId: string) => {
  if (requestMap.has(requestId)) {
    const { controller } = requestMap.get(requestId)!
    if (controller) {
      controller.abort()
      deleteReqMapItem(requestId)
    }
  }
}

/**
 * @description 取消全部请求
 */
export const cancelAllRequest = () => {
  requestMap.forEach((v, k) => !v.cancelConfig!.skipFromCancelAllQueue && cancelSingleRequest(k))
}
